import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

/** Affichage des étapes d'application
  * du patch de jeu vidéo
  * Ce panel centralise les commandes
  *
  * @author     Nemesis (nemesis_tt@yahoo.fr)
  * @version    05/05/04
  */

public class Etapes extends JPanel {

// Fenêtre principale
// ------------------
    private Patcheur patcheur;
    
// Etat d'avancement et appli
// --------------------------
    private boolean pause = false;
    private Application appli;
    
// Les éléments de la vue (IHM)
// ----------------------------
    
    /** Evolution des images */
    private final int AVANT = 0;
    private final int PENDANT = 1;
    private final int APRES = 2;
    
    /** Zones d'images */
    private final int NB = 4;
    private final int DUMP = 0;
    private final int CHECK = 1;
    private final int PATCH = 2;
    private final int FINI = 3;
    
    /** Répertoire des images et extensions */
    private final String REP = "/Images/";
    private final String ANIM = "_anim";
    private final String EXT = ".gif";
    
    /** Noms des éléments */
    private final String vide = "00_vide";
    private final String[] noms = {
        "01_dump",
        "02_check",
        "03_patch",
        "04_fini"};
    private final String[] descriptions = {
        "Création de l'image",
        "Vérification de l'image",
        "Application du patch",
        "Evolution"};
        
    /** Images des étapes */
    private ImageIcon[][] images = new ImageIcon[3][NB];
    private JLabel[] etapes = new JLabel[NB];
    
    /** Couleurs */
    private Color coul_evol = Color.blue;
    private Color coul_action = Color.red;
    
    /** Etape actuelle */
    private int etape = -1; // Initiale
    private Evolution evol;

// Le constructeur
// ---------------

    /** Construire le panel d'étapes */
    public Etapes(Patcheur patcheur_) {
        super();
        patcheur = patcheur_;
        
        // Paramètres de la fenêtre
        setBackground(Patcheur.coul_fond);

        //  Définition du layout de la zone
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints layout = new GridBagConstraints();
        setLayout(gridbag);
        layout.fill=GridBagConstraints.BOTH;
        
        // Chargement des images
        layout.insets = new Insets(10,10,10,10);
        for (int i=0; i<NB; i++) {
            String chemin = REP + vide + EXT;
            images[AVANT][i] = new ImageIcon(
                Etapes.class.getResource(REP + vide + EXT), descriptions[i]);
            images[PENDANT][i] = new ImageIcon(
                Etapes.class.getResource(REP + noms[i] + ANIM + EXT), descriptions[i]);
            images[APRES][i] = new ImageIcon(
                Etapes.class.getResource(REP + noms[i] + EXT), descriptions[i]);
            // Caractéristiques du texte et du label
            etapes[i] = new JLabel(descriptions[i],JLabel.CENTER);
            layout.weightx = 1;
            layout.gridx = 0;
            layout.weighty = 1;
            layout.gridy = i;
            gridbag.setConstraints(etapes[i], layout);
            etapes[i].setVerticalTextPosition(JLabel.BOTTOM);
            etapes[i].setHorizontalTextPosition(JLabel.CENTER);
            add(etapes[i]);
            // Commande de lancement/arrêt
            etapes[i].addMouseListener(new Lancement_Arret());
        }
        // Initialisation des images
        setEtape(etape);
    }
    
    /** Action de lancement/arrêt */
    private class Lancement_Arret extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            switch (etape) {
            case -1:
                appli = new Application();
                appli.start();
                break;
            default:
                // Relancement ou pause
                pause = !pause;
            }
        }
    }
    
    /** Changement d'étape
     * 
     * @param   e   etape désirée
     */
    private void setEtape(int e) {
        // Validation du paramètre
        e = Math.min(e,NB-1);
        // Mise à jour des éléments
        for (int i=0; i<e; i++) {
            etapes[i].setIcon(images[APRES][i]);
            etapes[i].setForeground(null);
        }
        if (e>=0) {
            etapes[e].setIcon(images[PENDANT][e]);
            etapes[e].setForeground(coul_evol);
        }
        for (int i=e+1; i<NB; i++) {
            etapes[i].setIcon(images[AVANT][i]);
        }
        // Configuration de l'élément d'évolution
        etapes[NB-1].setForeground(coul_action);
        if ((etape!=-1 && etape!=NB-1)
        && (e==-1 || e==NB-1)) {
            evol.termine();
        } else if ((etape==-1 || etape==NB-1)
        && (e!=-1 && e!=NB-1)) {
            evol = new Evolution();
            evol.start();
        }
        switch (e) {
            case -1:
                etapes[NB-1].setText("Cliquez pour démarrer");
                break;
            case NB-1:
                etapes[NB-1].setText("Fini ! Bon jeu !");
                break;
            default:
                if (pause)
                    etapes[NB-1].setText("Cliquez pour reprendre");
                else
                    etapes[NB-1].setText("Cliquez pour arrêter");
        }
        etape = e;
    }
    
    /** Gestion de l'appplication
     */
    private class Application extends Thread {
        private boolean fin = false;
        
        /** Exécution */
        public void run() {
            String iso = patcheur.getOptions().getIso();
            
            setEtape(DUMP);
            // Création de dossiers, si nécessaire
            File iso_f = new File(iso);
            iso_f.getParentFile().mkdirs();
            // Test de copie de CD
            if (patcheur.getOptions().getCopieCD()) {
                int res;
                // Ecrasement ?
                if (iso_f.exists()) {
                    JTextArea jte = new JTextArea();
                    jte.setEditable(false);
                    jte.setOpaque(false);
                    jte.setText("Souhaitez-vous écrasez l'image ?");
                    res = JOptionPane.showConfirmDialog
                        (null, jte, "Confirmation...",
                         JOptionPane.YES_NO_OPTION, 
                         JOptionPane.WARNING_MESSAGE);
                
                    if (res != JOptionPane.OK_OPTION)
                        Logueur.loguer(new String("Annulation"),
                                       Logueur.ERROR_ISO);
                }
                if (Logueur.noError()) {
                    // Lancement de la copie de CD
                    ImageCD dumpCD = new ImageCD(patcheur.getOptions().getLettreCD(),iso);
                    dumpCD.start();
                    dumpCD.attendre();
                }
            }
            
            if (patcheur.getOptions().getSauvegarde() && Logueur.noError()) {
                // Lancement de la sauvegarde de l'image CD
                Sauvegarde sauv = new Sauvegarde(iso);
                sauv.start();
                sauv.attendre();
            }
            
            if (Logueur.noError()) {
                setEtape(CHECK);
                // Non implémenté
            }
            
            if (Logueur.noError()) {
                setEtape(PATCH);
                // Initialisation du patch
                Patch patch = patcheur.getPatch();
                patch.setIso(iso);
                // Appplication du patch
                patch.appliquer();
            }
            
            if (Logueur.noError()) {
                setEtape(FINI);
            }
        }
        
        /** Exécution */
        public void termine() {
            fin = true;
        }
    }
    /** Gestion du clignotement
     */
    private class Evolution extends Thread {
        /** Delai de clignotement en millisecondes */
        private final int delai = 200;
        private boolean fin = false;
        
        /** Exécution */
        public void run() {
            while(etape>=0 && !fin) {
                // Couleur standard
                try { sleep(delai); }
                catch (Exception e) {};
                etapes[NB-1].setForeground(null);
                // Couleur spéciale
                try { sleep(delai); }
                catch (Exception e) {};
                etapes[NB-1].setForeground(coul_action);
            }
        }
        
        /** Exécution */
        public void termine() {
            fin = true;
        }
    }
}
